package com.kedacom.ctsp.authz.security.provider;

import com.kedacom.ctsp.authz.security.captcha.CaptchaErrorException;
import com.kedacom.ctsp.authz.security.captcha.CaptchaProperties;
import com.kedacom.ctsp.authz.security.captcha.CaptchaService;
import com.kedacom.ctsp.authz.security.util.UserBeanUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * AuthenticationFilter that supports rest login(json login) and form login.
 * Json Rest登录
 *
 * @author sunchenjie
 */
@Slf4j
public class JsonAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

    @Autowired
    private CaptchaProperties captchaProperties;

    @Autowired(required = false)
    private CaptchaService captchaService;

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {

        UserBean authUser = UserBeanUtil.createLoginUserBean(request);
        // 检验 验证码
        if (captchaProperties.getEnable() && authUser != null) {
            boolean b = captchaService.checkCaptcha(request, authUser.getCaptcha());
            if (!b) {
                CaptchaErrorException ex = new CaptchaErrorException();
                throw new BadCredentialsException(ex.getMessage(), ex);
            }
        }

        request.setAttribute("authUser", authUser);

        //attempt Authentication when Content-Type is json
        // 检测是否是json请求
        if (UserBeanUtil.isJsonRequest(request)) {
            UsernamePasswordAuthenticationToken authRequest = null;

            // 组装 UsernamePasswordAuthenticationToken
            if (authUser != null) {
                authRequest = new UsernamePasswordAuthenticationToken(
                        authUser.getUsername(), authUser.getPassword());

            } else {
                authRequest = new UsernamePasswordAuthenticationToken(
                        "", "");
            }
            setDetails(request, authRequest);
            return this.getAuthenticationManager().authenticate(authRequest);
        }
        // 如果是post请求提交
        else {
            return super.attemptAuthentication(request, response);
        }
    }
}